package com.kavian.test.db;

import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;

import com.kavian.common.util.UuidUtil;

/**
 * 
 * JDBC连接池
 * 
 * @author kavian
 * 
 */
public class JdbcPool {

	final static String DRIVER = "com.mysql.jdbc.Driver";
	final static String URL = "jdbc:mysql://localhost:3306/test";
	final static String USER = "root";
	final static String PASSWORD = "root";

	static Connection conn;
	static PreparedStatement pstm;
	static ResultSet rs;

	public JdbcPool() {
		initial(DRIVER, URL, USER, PASSWORD);
	}

	/**
	 * 初始化
	 * 
	 * @param driver
	 *            驱动
	 * @param url
	 *            连接名
	 * @param userName
	 *            用户名
	 * @param password
	 *            密码
	 */
	private static void initial(String driver, String url, String user, String password) {
		try {
			if(null == conn){
				Class.forName(driver);
				conn = DriverManager.getConnection(url, user, password);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 新增/修改/删除
	 */
	public boolean executeSql(String sql, Object... obj) {
		try {
			if (null == obj) {
				return false;
			}

			pstm = conn.prepareStatement(sql);

			for (int i = 0; i < obj.length; i++) {
				if (null != obj[i]) {
					pstm.setObject(i + 1, obj[i]);
				}
			}

			pstm.executeUpdate();

			return true;

		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}

	/**
	 * 获得查询出来的对象
	 * 
	 * @param clazz
	 *            类
	 * @param sql
	 *            sql语句
	 * @param pars
	 *            参数
	 * @return
	 */
	public static <T> T findObject(Class<T> clazz, String sql) {
		initial(DRIVER, URL, USER, PASSWORD);
		T t = null;

		// 获得数据库连接
		// conn = getConnection();
		try {
			// 给sql的参数赋值并执行查询
			pstm = conn.prepareStatement(sql);
//			if (pars.length > 0) {
//				for (int i = 0; i < pars.length; i++) {
//					pstm.setObject(i + 1, pars[i]);
//				}
//			}
			rs = pstm.executeQuery();

			// 根据查询结果获得该rs对应的ResultSetMetaData对象
			ResultSetMetaData rsmd = rs.getMetaData();
			// 获得返回的列的数量
			int count = rsmd.getColumnCount();
			// 该数组存放列的名称
			String[] columns = new String[count];
			// 向数组中存放列的名称
			for (int i = 0; i < columns.length; i++) {
				columns[i] = rsmd.getColumnLabel(i + 1);
			}

			// 如果结果中有数据存在
			if (rs.next()) {
				// 根据pojo的class反射获得其对象
				t = clazz.newInstance();
				// 获得pojo所有的方法
				Method[] methods = clazz.getMethods();

				for (int i = 0; i < columns.length; i++) {
					// 根据列名获得set方法<由于没有映射文件，要求pojo中的属性必须和列名相同>
					String column = columns[i];
					String methodName = "set"
							+ column.substring(0, 1).toUpperCase()
							+ column.substring(1);

					// 根据获得的方法数组去迭代 如果方法名称和上面获得的set方法相同 就执行这个方法
					for (int j = 0; j < methods.length; j++) {
						Method method = methods[j];
						if (method.getName().equals(methodName)) {
							method.invoke(t, rs.getObject(column));
						}
					}
				}
			}

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			close();
		}

		return t;

	}

	/**
	 * 关闭连接
	 */
	public static void close() {
		try {
			if (null != rs) {
				rs.close();
			}
			if (null != pstm) {
				pstm.close();
			}
			if (null != conn) {
				conn.close();
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] args) {
		JdbcPool jdbc = new JdbcPool();
		String sql = "INSERT INTO proxy_ip(id,ip,port,is_valid) VALUES(?,?,?,?)";

		// Map<String, Object> map = new HashMap<String, Object>();
		// map.put("id", UuidUtil.getUuid());
		// map.put("ip", "1123");
		// map.put("port", "12");
		// map.put("is_valid", 1);

		Object[] obj = { UuidUtil.getUuid(), "12345", "2341", 1 };

		jdbc.executeSql(sql, obj);
	}

}